package com.xiyuan;

import com.xiyuan.smartutils.StrUtils;
import com.xiyuan.smartutils.Systems;
import com.xiyuan.smartutils.Threads;
import com.xiyuan.smartutils.constants.SignConstants;
import com.xiyuan.smartutils.constants.SysConstants;
import com.xiyuan.smartutils.control.Threadx;
import com.xiyuan.smartutils.logging.LogFactory;
import com.xiyuan.smartutils.logging.Logger;

import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;


/**
 * 系统工程监听类 ，由FCommand发起的命令在这里执行
 * <p>
 * 1. -s表示启动 2. -c表示工程退出 3. -i表示查看信息 4. -t表示测试配置文件（TODO 暂未实现） 5. -r表示重新加载配置（TODO 暂未实现） 6. -h表示帮助 7. -?表示帮助
 *
 * @version v1.0.0 @author lgz 2017-8-27 新建与整理
 */
final class SysMonitor extends Threadx implements SysConstants, SignConstants {
    
    private static final Logger logger = LogFactory.getLogger(SysMonitor.class);
    
    private ServerSocket serverSocket;
    private int port;
    
    // 只允许包创建实例
    SysMonitor(int port) {
        this.port = port;
    }
    
    /**
     * 线程名
     */
    protected String getThreadName() {
        return "XiyuanMonitor";
    }
    
    /**********************************************************************************/
    // 开启&关闭&循环运行
    /**********************************************************************************/
    
    /**
     * 开启
     */
    protected boolean openBefore() {
        try {
            serverSocket = new ServerSocket(port, 5, InetAddress.getByName("127.0.0.1"));
            serverSocket.setReuseAddress(true);
            return true;
        }
        catch (BindException e) {
            logger.error("启动监视线程失败，工程已启动或端口[boot.port]被占用");
            return false;
        }
        catch (Exception e) {
            logger.error("启动监视线程失败", e);
            return false;
        }
    }
    
    /**
     * 关闭
     */
    protected void closeAfter() {
        Threads.closeIgnoreException(serverSocket);
    }
    
    /**
     * 运行
     */
    public void loop() {
        Socket socket = null;
        String cmd = null;
        try {
            socket = serverSocket.accept();
            
            LineNumberReader line = new LineNumberReader(new InputStreamReader(socket.getInputStream()));
            String lineKey = line.readLine();
            if (!NAME.equals(lineKey)) {return;}
            
            cmd = line.readLine();
            if (INFO_C.equals(cmd)) {
                // 查看信息
                StringBuilder strb = new StringBuilder().append("响应结果:")
                        .append(_BR_)
                        .append("PID:")
                        .append(Systems.getPid())
                        .append(_BR_);
                
                socket.getOutputStream().write(StrUtils.getBytesUTF8(strb.toString()));
                socket.getOutputStream().flush();
            }
            else if (TEST_C.equals(cmd) || RELOAD_C.equals(cmd)) {
                // 测试配置文件和重新加载配置文件 TODO 暂未实现
                StringBuilder strb = new StringBuilder().append("响应结果:")
                        .append(_BR_)
                        .append("暂未实现")
                        .append(_BR_);
                
                socket.getOutputStream().write(StrUtils.getBytesUTF8(strb.toString()));
                socket.getOutputStream().flush();
            }
            else if (HELP_C.equals(cmd) || QUESTION_C.equals(cmd)) {
                // 帮助
                StringBuilder strb = new StringBuilder().append("响应结果:")
                        .append(_BR_)
                        .append("-s    启动工程")
                        .append(_BR_)
                        .append("-c    关闭工程")
                        .append(_BR_)
                        .append("-i    查看信息")
                        .append(_BR_)
                        .append("-t    测试配置文件")
                        .append(_BR_)
                        .append("-r    重新加载配置")
                        .append(_BR_)
                        .append("-h    帮助")
                        .append(_BR_)
                        .append("-?    帮助")
                        .append(_BR_);
                
                socket.getOutputStream().write(StrUtils.getBytesUTF8(strb.toString()));
                socket.getOutputStream().flush();
            }
        }
        catch (Exception e) {
            logger.error(e);
        }
        finally {
            Threads.closeIgnoreException(socket);
            if (CLOSE_C.equals(cmd)) {
                System.exit(0);
                // 接受到退出工程命令
            }
        }
    }
}
